package com.song.workpool;

import java.util.LinkedList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 工作线程池
 * 
 */
@SuppressWarnings("rawtypes")
public class WorkThreadPool extends ThreadGroup {
	private Log log = LogFactory.getLog(WorkThreadPool.class);
	private boolean isAlive; // 标志线程池是否开启
	
	private LinkedList<Task> taskQueue; // 线程池中的任务队列
	private int threadID; // 线程池中的线程ID
	private String threadName = "work";	//线程名称
	private static int threadPoolId; // 线程池ID
	
	/**
	 * 构造函数
	 * @param threadName	线程名称
	 * @param threadNum		线程池内线程数
	 */
	public WorkThreadPool(String threadName,int threadNum) {
		super(threadName+"-"+"ThreadPool-" + (threadPoolId++));
		super.setDaemon(true);
		this.threadName = threadName;
		this.isAlive = true;
		this.taskQueue = new LinkedList<Task>(); // 初始化任务队列
		for (int i = 0; i < threadNum; i++) {
			new WorkThread().start();	//初始化线程池内线程
		}
	}

	/** 添加新任务如工作线程池 */
	public synchronized void addTask(Task task) {
		if (!this.isAlive) {
			throw new IllegalStateException(); // 线程池被关闭，抛出异常
		}
		if (task != null) {
			this.taskQueue.add(task); // 添加任务到任务队列的尾部
			notify(); // 唤醒工作线程，获取任务
		}
	}

	/** 获取任务，若无任务，则等待 */
	protected synchronized Task getTask()
			throws InterruptedException {
		while (this.taskQueue.size() == 0) {
			if (!this.isAlive) {	//若线程池已关闭，不进行等待，直接返回null
				return null;	
			}
			wait();
		}
		return (Task) this.taskQueue.removeFirst();	//从任务队列中取出最早入队列的任务，并将该任务从队列中删除
	}

	/** 关闭线程池，所有线程停止，不再执行任务 */
	public synchronized void closeThreadPool() {
		if (isAlive) {
			this.isAlive = false;
			this.taskQueue.clear(); // 清除未处理的任务
			this.interrupt(); // 中断线程池中所有线程
		}
	}

	/**关闭线程池，并等待线程池中的所有任务被运行完 此过程中，不再接受新任务 */
	public void closeThreadPoolAfterTaskOver() {
		synchronized (this) {
			isAlive = false;
			notifyAll();
		}
		// 等待所有线程完成
		// 建立新的线程数组，activeCount方法获取线程池中活动线程的数
		Thread[] threads = new Thread[this.activeCount()];
		// 将线程池中的活动线程复制到新创建的线程组中
		int count = this.enumerate(threads);
		for (int i = 0; i < count; i++) {
			try {
				threads[i].join(); // 等待线程运行结束
			} catch (InterruptedException e) {
				log.error("",e);
			}
		}
	}

	/**工作线程*/
	public class WorkThread extends Thread {
		public WorkThread() {
			// DBWorkThreadPool.this 该线程所在的线程组对象，即当前线程池对象
			// 第二个参数为线程名字
			super(WorkThreadPool.this, threadName+"-"+"Thread-" + (threadID++));
		}
		
		public void run(){
			while(!isInterrupted()){
				//获取任务
				Task task = null;
				try{
					task = getTask();
				}catch(InterruptedException ex){
					log.error("InterruptedException",ex);
				}
				
				//只要线程池的任务列表不为空，getSaveObjectTask()方法总能获得一个任务
				//若返回为null,则表示线程池中已经没有任务，而且线程池已经被关闭
				if(task==null){
					return ;
				}
				
				//运行任务，捕获异常
				try {
					task.taskPerform();
				} catch (Throwable t) {
					//当线程组中的线程有未被捕获的异常发生时，
					//JVM会调用uncaughtException方法
					uncaughtException(this, t);
				}
			}
		}
	}

}
